package com.bitcoin.scheduler.websocket.client.gateio.impl;

import com.bitcoin.scheduler.websocket.client.ApiCallback;
import com.bitcoin.scheduler.websocket.client.ApiWebSocketListener;
import com.bitcoin.scheduler.websocket.client.gateio.GateIoApiWebSocketClient;
import com.bitcoin.scheduler.websocket.client.gateio.domain.KlineQueryResponse;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.WebSocket;

import java.io.Closeable;
import java.util.List;
import java.util.Map;

/**
 * Binance API WebSocket client implementation using OkHttp.
 */
public class GateIoApiWebSocketClientImpl implements GateIoApiWebSocketClient, Closeable {

    private final OkHttpClient client;

    public GateIoApiWebSocketClientImpl(OkHttpClient client) {
        this.client = client;
    }

    @Override
    public Closeable klineQuery(Integer id, String market, Integer start, Integer end, Integer interval, ApiCallback<KlineQueryResponse> callback) {
        List<Object> params = Lists.newArrayList();
        params.add(market);
        params.add(start);
        params.add(end);
        params.add(interval);
        Map<String, Object> request = Maps.newConcurrentMap();
        request.put("id", id);
        request.put("method", "kline.query");
        request.put("params", params);
        String message = null;
        try {
            message = new ObjectMapper().writeValueAsString(request);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return createNewWebSocket(message, new ApiWebSocketListener<>(callback, KlineQueryResponse.class));
    }

    /**
     * @deprecated This method is no longer functional. Please use the returned {@link Closeable} from any of the other methods to close the web socket.
     */
    @Override
    public void close() {
    }

    private Closeable createNewWebSocket(String message, ApiWebSocketListener<?> listener) {
        String streamingUrl = "wss://ws.gate.io/v3/";
        Request request = new Request.Builder().url(streamingUrl).build();
        final WebSocket webSocket = client.newWebSocket(request, listener);
        webSocket.send(message);
        return () -> {
            final int code = 1000;
            listener.onClosing(webSocket, code, null);
            webSocket.close(code, null);
            listener.onClosed(webSocket, code, null);
        };
    }
}
